package nancal.mp.mvc.devops


import nancal.mp.db.mongo.JenkinsLanguageEnum
import nancal.mp.db.mongo.mor
import nancal.mp.model.OpsDeployModel
import nancal.mp.service.NexusService
import nancal.mp.service.git.GitApiService

import nbcp.base.comm.ApiResult
import nbcp.base.comm.JsonMap
import nbcp.base.extend.*
import nbcp.base.utils.XmlUtil
import nbcp.mvc.HttpContext
import nbcp.myoql.db.mongo.queryById
import org.dom4j.io.SAXReader
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Lazy
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.time.LocalDateTime


@RequestMapping("/dev")
@RestController
class MavenController {

    @Autowired
    @Lazy
    private lateinit var nexusService: NexusService


    class NexusComponentInfo {
        var groupId = ""
        var artifactId = ""
        var packageName = ""
        var defVersion = ""
        var description = ""
        var nexusVersion = ""
        var lastModified = LocalDateTime.MIN
        var extension = "";

        fun loadFromPom(pomContent: String) {
            var doc = SAXReader().read(pomContent.byteInputStream())


            //如果找不到，就找 parent 节点！
            this.groupId = XmlUtil.getSingleElement(doc, "project", "groupId")?.text.AsString {
                XmlUtil.getSingleElement(doc, "project", "parent", "groupId")?.text.AsString()
            };


            this.artifactId =
                XmlUtil.getSingleElement(doc, "project", "artifactId")?.text.AsString();
            this.defVersion = XmlUtil.getSingleElement(doc, "project", "version")?.text.AsString{
                XmlUtil.getSingleElement(doc, "project", "parent", "version")?.text.AsString()
            }
            this.description =
                XmlUtil.getSingleElement(doc, "project", "description")?.text.AsString();
            this.extension = XmlUtil.getSingleElement(doc, "project", "packaging")?.text.AsString();
        }

    }

    @PostMapping("/nexus/component/info")
    fun getComponentInfo(@org.springframework.web.bind.annotation.RequestBody query: OpsDeployModel): ApiResult<NexusComponentInfo> {
        //HttpClientGatewayHostEvent 解析时使用。
        HttpContext.request.setAttribute("[env_code]", query.targetEnv);

        var gitData = mor.dev.gitData.queryById(query.gitId).toEntity()!!;
        if (gitData.isLib == false) {
            return ApiResult()
        }
        var currentFolder = gitData.folders.firstOrNull { it.name == query.name }

        if (currentFolder == null) {
            return ApiResult.error("找不到 name: ${query.name}")
        }
        var gitServer = mor.dev.gitServer.queryById(gitData.server.id).toEntity()!!

        var gitService = GitApiService.getInstance(gitServer.gitServerType);

        var info = NexusComponentInfo();
        var paths = currentFolder.path.split("/").toMutableList();
        paths.removeAll { it == "." || it.isEmpty() }


        if (gitData.language == JenkinsLanguageEnum.Java) {

            paths.add("pom.xml")
            var pomResult = gitService.getRawFile(
                gitServer.host,
                gitData.accessToken,
                gitData.group,
                gitData.project,
                query.gitBranch,
                paths.joinToString("/")
            )

            if (pomResult.data == null) {
                return ApiResult.of(info);
            }
            var pomContent = pomResult.data!!.toUtf8String();

            info.loadFromPom(pomContent);

            if (gitData.isLib) {
                //向上找
                if (info.groupId.isEmpty()) {
                    //看上面的 pom.xml
                    if (query.name.remove('.', '/').HasValue) {

                        paths.removeAt(paths.size - 2);

                        pomResult = gitService.getRawFile(
                            gitServer.host,
                            gitData.accessToken,
                            gitData.group,
                            gitData.project,
                            query.gitBranch,
                            paths.joinToString("/")
                        )

                        if (pomResult.data == null) {
                            return ApiResult.of(info);
                        }
                        pomContent = pomResult.data!!.toUtf8String();

                        var info2 = NexusComponentInfo();
                        info2.loadFromPom(pomContent);
                        info.groupId = info2.groupId;

                        //再向上找
                        if (info.groupId.isEmpty()) {
                            //看上面的 pom.xml
                            if (query.name.remove('.').split("/").size >= 2) {

                                paths.removeAt(paths.size - 2);

                                pomResult = gitService.getRawFile(
                                    gitServer.host,
                                    gitData.accessToken,
                                    gitData.group,
                                    gitData.project,
                                    query.gitBranch,
                                    paths.joinToString("/")
                                )

                                if (pomResult.data == null) {
                                    return ApiResult.of(info);
                                }
                                pomContent = pomResult.data!!.toUtf8String();


                                info2 = NexusComponentInfo();
                                info2.loadFromPom(pomContent);
                                info.groupId = info2.groupId;

                            }
                        }
                    }
                }
            }

            var nexusVersion =
                nexusService.getLastedJarVersion(query.targetEnv, info.groupId, info.artifactId, null)

            if (nexusVersion.hasError) {
                return ApiResult.error(nexusVersion.msg)
            }

            if (nexusVersion.data == null || nexusVersion.data!!.version.isNullOrEmpty()) {
                return ApiResult.of(info);
            }

            info.nexusVersion = nexusVersion.data!!.version
            info.lastModified = nexusVersion.data!!.lastModified
        } else if (gitData.language == JenkinsLanguageEnum.Node) {
            paths.add("package.json")
            var packageResult = gitService.getRawFile(
                gitServer.host,
                gitData.accessToken,
                gitData.group,
                gitData.project,
                query.gitBranch,
                paths.joinToString("/")
            )

            if (packageResult.hasError) {
                return ApiResult.error(packageResult.msg)
            }

            var packageContent = packageResult.data?.toUtf8String();
            if (packageContent.isNullOrEmpty()) {
                return ApiResult.of(info);
            }

            var packageJson = packageContent!!.FromJson<JsonMap>()!!

            info.packageName = packageJson.get("name").AsString()
            info.defVersion = packageJson.get("version").AsString()
            info.description = packageJson.get("description").AsString()


            var nexusVersion = nexusService.getLastedNpmVersion(query.targetEnv, info.packageName)

            if (nexusVersion.hasError) {
                return ApiResult.error(nexusVersion.msg)
            }
            if (nexusVersion.data == null) {
                return ApiResult.of(info);
            }

            info.nexusVersion = nexusVersion.data!!.version
            info.lastModified = nexusVersion.data!!.lastModified
        }


        return ApiResult.of(info);
    }
}